#ifndef UTILITY_H
#define UTILITY_H

#include "opencv2/core/types.hpp"
#include <QString>
#include <QVariant>
#include <QVariantMap>
#include <QVariantList>
#include <iostream>
#include <sstream>
#include <yaml-cpp/yaml.h>

std::string QVariantMapToString(const QVariantMap &map, int indentLevel = 0);
std::string QVariantListToString(const QVariantList &list, int indentLevel);



inline std::string QVectorQVariantMapToString(const QVector<QVariantMap> &vec) {
    std::ostringstream out;
    int index = 0;

    for (const QVariantMap &map : vec) {
        out << "Map " << index++ << ":\n";  // 输出每个 QVariantMap 的索引
        out << QVariantMapToString(map, 1);  // 使用一级缩进
        out << "\n";  // 在每个 map 之后添加一个新行以提高可读性
    }

    return out.str();
}

inline std::string QVariantListToString(const QVariantList &list, int indentLevel = 0) {
    std::ostringstream out;
    std::string indent(indentLevel * 2, ' '); // Create indentation string
    int index = 0;

    for (const QVariant &value : list) {
        out << indent << "Element " << index++ << ": ";
        if (value.type() == QVariant::Map) {
            out << "\n" << QVariantMapToString(value.toMap(), indentLevel + 1);
        } else if (value.type() == QVariant::List) {
            out << "\n" << QVariantListToString(value.toList(), indentLevel + 1);
        } else {
            out << value.toString().toStdString() << "\n";
        }
    }

    return out.str();
}


inline std::ostream& operator<<(std::ostream &os, const QVariantList &vec) {
    os << QVariantListToString(vec);
    return os;
}

inline std::ostream& operator<<(std::ostream &os, const QVector<QVariantMap> &vec) {
    os << QVectorQVariantMapToString(vec);
    return os;
}

inline std::ostream& operator<<(std::ostream &os, const QVariantMap &map) {
    os << QVariantMapToString(map);
    return os;
}
inline std::ostream& operator<<(std::ostream &os, const QStringList &list) {
    os << "[";
    for (int i = 0; i < list.size(); ++i) {
        os << list.at(i).toStdString();
        if (i < list.size() - 1) {
            os << ", ";
        }
    }
    os << "]";
    return os;
}

inline std::ostream& operator<<(std::ostream &os, const cv::Rect &rect) {
    os << "Rect(x=" << rect.x << ", y=" << rect.y << ", width=" << rect.width << ", height=" << rect.height << ")";
    return os;
}

// 示例：重载 << 操作符以打印 cv::Rect2d（双精度版本）
inline std::ostream& operator<<(std::ostream &os, const cv::Rect2d &rect) {
    os << "Rect2d(x=" << rect.x << ", y=" << rect.y << ", width=" << rect.width << ", height=" << rect.height << ")";
    return os;
}

template <typename K, typename V>
std::ostream& operator<<(std::ostream& os, const std::map<K, V>& map) {
    os << "{";
    for (auto it = map.cbegin(); it != map.cend(); ++it) {
        os << it->first << ": " << it->second;
        if (std::next(it) != map.cend()) {
            os << ", ";
        }
    }
    os << "}";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << vec[i];
        if (i != vec.size() - 1) {
            os << ", ";
        }
    }
    os << "]";
    return os;
}

QVariant yamliteratorQVariant(YAML::const_iterator param);
QVariant yamlNodeQVariant(YAML::Node param);
#endif // UTILITY_H
